package com.unibuy.smartdevice.tools;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Environment;
import android.text.InputType;
import android.util.Base64;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.fragment.app.DialogFragment;

import com.androidadvance.topsnackbar.TSnackbar;
import com.unibuy.smartdevice.exception.Logs;
import com.google.android.material.textfield.TextInputEditText;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Tools {
    private static Window window;
    private Context context;
    private AlertDialog dialog;
    private Logs logs;
    private static File externalFilesDir;

    public static void setExternalFilesDir(Context context) {
//        externalFilesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
        externalFilesDir = context.getExternalFilesDir(null);
    }

    public static File getExternalFilesDir() {
        return externalFilesDir;
    }

    public static String getStringByNow(String dateType) {
        // 取得當前日期
        Date date = new Date();

        // 設定日期格式 yyyy_MM_dd
        SimpleDateFormat sdf = new SimpleDateFormat(dateType, Locale.getDefault());

        return sdf.format(date);
    }

    public static String getStringByDay(int day, String dateType) {
        // 取得當前日期
        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.DAY_OF_YEAR, day);

        Date date = calendar.getTime();

        // 設定日期格式
        SimpleDateFormat sdf = new SimpleDateFormat(dateType, Locale.getDefault());

        return sdf.format(date);
    }

    public static String getStringByHour(int hour, String dateType) {
        // 取得當前日期
        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.HOUR_OF_DAY, hour);

        Date date = calendar.getTime();

        // 設定日期格式
        SimpleDateFormat sdf = new SimpleDateFormat(dateType, Locale.getDefault());

        return sdf.format(date);
    }

    public static String getStringByMinute(int minute, String dateType) {
        // 取得當前日期
        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.MINUTE, minute);

        Date date = calendar.getTime();

        // 設定日期格式
        SimpleDateFormat sdf = new SimpleDateFormat(dateType, Locale.getDefault());

        return sdf.format(date);
    }

    public static void setWindow(Window wd) {
        window = wd;
    }

    public static Window getWindow() {
        return window;
    }

    public static int threadCount() {
        int threadCount = Thread.activeCount();
        return threadCount;
    }

    public static void threadInfos() {
        Logs logs = new Logs(Tools.class);

        Map<Thread, StackTraceElement[]> allThreads = Thread.getAllStackTraces();

        // 列出所有執行緒
        logs.debug("------------- Thread Sta -------------");
        for (Thread thread : allThreads.keySet()) {
            logs.debug("Thread Name:" + thread.getName() + " Thread ID:" + thread.getId() + " Thread State:" + getStateInChinese(thread.getState()));
        }
        logs.debug("------------- Thread End -------------");
    }

    public static String getStateInChinese(Thread.State state) {
        switch (state) {
            case NEW:
                return "新建";
            case RUNNABLE:
                return "可執行";
            case BLOCKED:
                return "阻塞";
            case WAITING:
                return "等待";
            case TIMED_WAITING:
                return "計時等待";
            case TERMINATED:
                return "已終止";
            default:
                return "未知狀態";
        }
    }

    //"yyyyMMddhhmmss"
    public static String getTimeStampByNow(String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, Locale.US);
        String timeStamp = simpleDateFormat.format(new Date());
        return timeStamp;
    }

    public static String generateTimeBasedUUID() {
        // 獲取當前時間戳
        long timestamp = System.currentTimeMillis();
        // 添加隨機數增加唯一性
        int randomNum = new Random().nextInt(100000); // 生成 0-99999 的隨機數
        // 組合時間戳和隨機數
        return timestamp + String.format("%05d", randomNum); // 格式化隨機數補足 5 位
    }

    public static String randomReplace(String input, double probability) {
        StringBuilder result = new StringBuilder();
        Random random = new Random();

        for (char c : input.toCharArray()) {
            // 按機率替換為 *
            if (random.nextDouble() < probability) {
                result.append('*');
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    public abstract static class DialogEditTextOnClickListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    }

    public static String toAES(String data, String HashKey, String HashIv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] encodedKey2 = HashKey.getBytes();
        SecretKey originalKey = new SecretKeySpec(encodedKey2, "AES");
        byte[] encodedIv2 = HashIv.getBytes();
        AlgorithmParameterSpec mAlgorithmParameterSpec = new IvParameterSpec(encodedIv2);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(1, originalKey, mAlgorithmParameterSpec);
        byte[] temp = cipher.doFinal(data.getBytes());
        return Base64.encodeToString(temp, 0);
    }

    public static String fromAES(String data, String HashKey, String HashIv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] encodedKey2 = HashKey.getBytes();
        SecretKey originalKey = new SecretKeySpec(encodedKey2, "AES");
        byte[] encodedIv2 = HashIv.getBytes();
        AlgorithmParameterSpec mAlgorithmParameterSpec = new IvParameterSpec(encodedIv2);
        byte[] temp = Base64.decode(data, 0);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(2, originalKey, mAlgorithmParameterSpec);
        byte[] decodeBytes = cipher.doFinal(temp);
        return new String(decodeBytes);
    }

    public static String getSHA256(String data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.reset();
            digest.update(data.getBytes(StandardCharsets.UTF_8));
            String result = String.format("%064x", new BigInteger(1, digest.digest()));
            return result;
        } catch (NoSuchAlgorithmException e2) {
            e2.printStackTrace();
            return "";
        }
    }

    public Tools(Context context, Logs logs) {
        this.context = context;
        this.logs = logs;
    }

    public void dialogClose() {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    public void dialogEditTextByLinearLayout(String title, LinearLayout layout, DialogEditTextOnClickListener dialogEditTextOnClickListener) {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }

        /*
        EditText editText1 = new EditText(context);
        editText1.setHint(textName1);
        editText1.setText("");
        editText1.setInputType(InputType.TYPE_CLASS_NUMBER);
        editText1.setSingleLine();

        EditText editText2 = new EditText(context);
        editText2.setHint(textName2);
        editText2.setText("");
        editText2.setInputType(InputType.TYPE_CLASS_NUMBER);
        editText2.setSingleLine();
        */

        // 使用 LinearLayout 放置兩個 EditText
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(50, 20, 50, 20); // 設定間距，讓視覺效果更好
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, // 寬度隨父層
                LinearLayout.LayoutParams.WRAP_CONTENT  // 高度根據內容調整
        );
        layout.setLayoutParams(layoutParams);
        layout.requestFocus();

        // 建立 AlertDialog
        dialog = new AlertDialog.Builder(context)
                .setTitle(title)
                .setView(layout) // 設置自定義的 View
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialogEditTextOnClickListener.onClick(dialog, which);
                        hideSystemBars();
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        hideSystemBars();
                    }
                })
                .create();

        dialog.setCanceledOnTouchOutside(false);
        dialog.setOnShowListener(dialogInterface -> {
            if (dialog.getWindow() != null) {
                dialog.getWindow().getDecorView().setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                );

                dialog.getWindow().getDecorView().clearFocus();
            }
        });

        dialog.show();
    }

    public void dialogEditText1(String title, String textName, DialogEditTextOnClickListener dialogEditTextOnClickListener) {
        LinearLayout linearLayout = new LinearLayout(context);

        EditText editText = new EditText(context);
        editText.setHint(textName);
        editText.setText("");
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
        editText.setSingleLine();

        linearLayout.addView(editText, 0);

        dialogEditTextByLinearLayout(title, linearLayout, new DialogEditTextOnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
    }

    public void setImmOpenByFocusChange(EditText editText) {
        editText.requestFocus();
        editText.setSelection(editText.getText().length());
        InputMethodManager imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
    }

    public void setImmHideByFocusChange(EditText editText) {
        editText.setOnFocusChangeListener((v, hasFocus) -> {
            // 隱藏導航列
            hideSystemBars();

            if (!hasFocus) {
                // 隱藏鍵盤
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
                }
            }
        });
    }

    public void setImmHideByFocusChange(TextInputEditText textInputEditText) {
        textInputEditText.setOnFocusChangeListener((v, hasFocus) -> {
            // 隱藏導航列
            hideSystemBars();

            if (!hasFocus) {
                // 隱藏鍵盤
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(textInputEditText.getWindowToken(), 0);
                }
            }
        });
    }

    public void hideSystemBars() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11+ 使用 WindowInsetsController
            WindowInsetsController controller = window.getInsetsController();
            if (controller != null) {
                controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                controller.setSystemBarsBehavior(
                        WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                );
            }
        } else {
            // 舊版使用 SystemUiVisibility
            window.getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION  // 隱藏導航列
                            | View.SYSTEM_UI_FLAG_FULLSCREEN      // 隱藏狀態列
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // 防止系統 UI 彈出
            );
        }

        // 設定為全屏模式，並隱藏 ActionBar
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 全屏
    }

    public void toastShortShow(String message) {
        Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    public void toastLongShow(String message) {
        Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_LONG).show();
    }

    public void snackbarShortShow(String message) {
        snackbarSecondShow( 34, 3, message);
    }

    public void snackbarLongShow(String message) {
        snackbarSecondShow( 34, 6, message);
    }

    public void snackbarSecondShow(int textSize, int second, String message) {
        if (context instanceof Activity) {
            View view = ((Activity) context).findViewById(android.R.id.content);
            TSnackbar snackbar = TSnackbar.make(view, message, TSnackbar.LENGTH_INDEFINITE);
            snackbar.setDuration(1000 * second);
            snackbar.setActionTextColor(Color.WHITE);
            View snackbarView = snackbar.getView();
            snackbarView.setBackgroundColor(Color.BLACK);
            snackbarView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

            // **將寬度設為全螢幕**
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,  // **寬度 MATCH_PARENT**
                    ViewGroup.LayoutParams.WRAP_CONTENT   // 高度根據內容自適應
            );
            layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;  // **讓 Snackbar 出現在底部**
            snackbarView.setLayoutParams(layoutParams);

            int textViewId = context.getResources().getIdentifier("snackbar_text", "id", context.getPackageName());
            if (textViewId != 0) {
                TextView textView = snackbarView.findViewById(textViewId);
                textView.setTextColor(Color.WHITE);
                textView.setTextSize(textSize);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
            }

            snackbar.show();
        } else {
            toastLongShow(message);
        }
    }
    public void snackbarShowOnClick(String message, String buttonName, View.OnClickListener onClickListener) {
        snackbarSecondShow(34, 6, message, buttonName, onClickListener);
    }

    public void snackbarSecondShow(int textSize, int second, String message, String buttonName, View.OnClickListener onClickListener) {
        if (context instanceof Activity) {
            View view = ((Activity) context).findViewById(android.R.id.content);
            TSnackbar snackbar = TSnackbar.make(view, message, TSnackbar.LENGTH_INDEFINITE);
            snackbar.setDuration(1000 * second);
            snackbar.setActionTextColor(Color.WHITE);
            View snackbarView = snackbar.getView();
            snackbarView.setBackgroundColor(Color.BLACK);
            snackbarView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

            // **將寬度設為全螢幕**
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,  // **寬度 MATCH_PARENT**
                    ViewGroup.LayoutParams.WRAP_CONTENT   // 高度根據內容自適應
            );
            layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;  // **讓 Snackbar 出現在底部**
            snackbarView.setLayoutParams(layoutParams);

            int textViewId = context.getResources().getIdentifier("snackbar_text", "id", context.getPackageName());
            if (textViewId != 0) {
                TextView textView = snackbarView.findViewById(textViewId);
                textView.setTextColor(Color.WHITE);
                textView.setTextSize(textSize);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
            }

            snackbar.setAction(buttonName, onClickListener);
            snackbar.show();
        } else {
            toastLongShow(message);
        }
    }

    public void gotoActivity(Class<?> cls) {
        logs.info("goto Activity:" + cls.getSimpleName());
        context.startActivity(new Intent(context, cls));
    }

    public static String readFile(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        fis.close();
        return bos.toString("UTF-8");
    }
}
